package cn.com.yusys.yusp.admin.Utils;

import cn.com.yusys.yusp.commons.config.ApplicationProperties;
import cn.com.yusys.yusp.commons.excel.*;
import cn.com.yusys.yusp.commons.file.ClientFactory;
import cn.com.yusys.yusp.commons.mapper.QueryModel;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

@Service
public class ExcelTaskManagerImpl implements ExcelTaskManager, InitializingBean{

    private final Logger logger = LoggerFactory.getLogger(ExcelTaskManagerImpl.class);
    @Autowired
    SqlSessionFactory sqlSessionFactory;
    @Autowired
    Executor taskExecutor;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    ApplicationProperties applicationProperties;
    @Autowired
    ClientFactory fileManagementClientFactory;
    @Autowired(
            required = false
    )
    ExcelRemoteCall excelRemoteCall;
    @Autowired(
            required = false
    )
    ExcelPrimaryId excelPrimaryId;
    @Value("${application.cache.ttl:720}")
    private int ttl;

    public ExcelTaskManagerImpl() {
    }

    //执行excel导出操作
    public String addExcelExportTask(String sqlId, Integer fetchSize, QueryModel queryModel, String clazzName) {
        String taskId = "failure";
        taskId = ExcelImportExportUtil.addRedisTaskInfo("export", this.stringRedisTemplate, (long)this.ttl);

        try {
            Class<?> clazz = Class.forName(clazzName);
            ExcelExportThread exportTask = new ExcelExportThread(sqlId, fetchSize, queryModel, taskId, clazz, this.stringRedisTemplate, this.sqlSessionFactory, this.excelRemoteCall, this.fileManagementClientFactory, (long)this.ttl);
            this.taskExecutor.execute(exportTask);
        } catch (ClassNotFoundException var8) {
            var8.printStackTrace();
        }

        return taskId;
    }

    //
    public String addExcelExportTaskByDataList(List<?> dataList, Integer fetchSize, QueryModel queryModel, String clazzName) {
        String taskId = "failure";
        taskId = ExcelImportExportUtil.addRedisTaskInfo("export", this.stringRedisTemplate, (long)this.ttl);

        try {
            Class<?> clazz = Class.forName(clazzName);
            ExcelExportThread exportTask = new ExcelExportThread(dataList, taskId, clazz, this.stringRedisTemplate, this.excelRemoteCall, this.fileManagementClientFactory, (long)this.ttl);
            this.taskExecutor.execute(exportTask);
        } catch (ClassNotFoundException var8) {
            var8.printStackTrace();
        }

        return taskId;
    }

    public String addExcelImportTask(MultipartFile file, String clazzName, String sqlId) {
        return this.addExcelImportTask(file, clazzName, sqlId, (Map)null);
    }

    public String addExcelImportTask(MultipartFile file, String clazzName, String sqlId, Map<String, Object> param) {
        String taskId = "failure";
        try {
            String fileName = this.generateImportFile(file);
            Class<?> clazz = Class.forName(clazzName);
            taskId = ExcelImportExportUtil.addRedisTaskInfo("import", this.stringRedisTemplate, (long)this.ttl);
            ExcelImportThread importTask = new ExcelImportThread(fileName, taskId, sqlId, clazz, this.stringRedisTemplate, this.sqlSessionFactory, this.excelRemoteCall, this.excelPrimaryId, param, (long)this.ttl);
            this.taskExecutor.execute(importTask);
        } catch (IOException var9) {
            this.logger.error(var9.getMessage());
        } catch (ClassNotFoundException var10) {
            this.logger.error(var10.getMessage());
        }

        return taskId;
    }

    private String generateImportFile(MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        String fileNameExt = fileName.substring(fileName.lastIndexOf(".") + 1);
        fileName = System.currentTimeMillis() + "_import." + fileNameExt;
        File newFile = new File(ExcelConstant.EXCEL_FILE_DIR + fileName);
        file.transferTo(newFile);
        return fileName;
    }

    public void afterPropertiesSet() throws Exception {
        String excelFileDir = this.applicationProperties.getExcel().getTempFileDir();
        if (excelFileDir != null) {
            if (!excelFileDir.endsWith("/") && !excelFileDir.endsWith("\\")) {
                ExcelConstant.EXCEL_FILE_DIR = excelFileDir + File.separator;
            } else {
                ExcelConstant.EXCEL_FILE_DIR = excelFileDir;
            }

            File fileDir = new File(ExcelConstant.EXCEL_FILE_DIR);
            if (!fileDir.exists()) {
                fileDir.mkdir();
            }
        }

        ExcelConstant.BATCH_SIZE = this.applicationProperties.getExcel().getBatchSize();
    }

    public String addExcelExportTask(String sqlId, Integer fetchSize, QueryModel queryModel, Class clazz) {
        String taskId = "failure";
        taskId = ExcelImportExportUtil.addRedisTaskInfo("export", this.stringRedisTemplate, (long)this.ttl);
        ExcelExportThread exportTask = new ExcelExportThread(sqlId, fetchSize, queryModel, taskId, clazz, this.stringRedisTemplate, this.sqlSessionFactory, this.excelRemoteCall, this.fileManagementClientFactory, (long)this.ttl);
        this.taskExecutor.execute(exportTask);
        return taskId;
    }

    public String addExcelExportTaskByDataList(List<?> dataList, Integer fetchSize, QueryModel queryModel, Class clazz) {
        String taskId = "failure";
        taskId = ExcelImportExportUtil.addRedisTaskInfo("export", this.stringRedisTemplate, (long)this.ttl);
        ExcelExportThread exportTask = new ExcelExportThread(dataList, taskId, clazz, this.stringRedisTemplate, this.excelRemoteCall, this.fileManagementClientFactory, (long)this.ttl);
        this.taskExecutor.execute(exportTask);
        return taskId;
    }
}
